package io.finer.erp.jeecg.bas.service.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;

import io.finer.erp.jeecg.bas.entity.*;
import io.finer.erp.jeecg.bas.service.*;
import io.finer.erp.jeecg.bas.vo.*;
import io.finer.erp.jeecg.stock.entity.StkInventory;
import io.finer.erp.jeecg.stock.entity.StkIoBill;
import io.finer.erp.jeecg.stock.entity.StkIoBillEntry;
import io.finer.erp.jeecg.stock.entity.StkIoMaterialLog;
import io.finer.erp.jeecg.stock.entity.StkPickUpEntry;
import io.finer.erp.jeecg.stock.service.IScan2ndService;
import io.finer.erp.jeecg.stock.service.IStkInventoryService;
import io.finer.erp.jeecg.stock.service.IStkIoBillEntryService;
import io.finer.erp.jeecg.stock.service.IStkIoBillService;
import io.finer.erp.jeecg.stock.service.IStkIoMaterialLogService;
import io.finer.erp.jeecg.stock.service.IStkPickUpEntryService;
import io.finer.erp.jeecg.stock.service.impl.ScanServiceImpl;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.checkerframework.checker.units.qual.A;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.MaterialConstant;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.api.client.util.Maps;
import com.google.common.collect.Lists;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import io.finer.erp.jeecg.bas.mapper.ZrkOrderProcessMapper;
import io.finer.erp.jeecg.bas.mapper.ZzShoporderMapper;
import io.finer.erp.jeecg.stock.entity.StkPickUpBill;
import io.finer.erp.jeecg.stock.service.IStkPickUpBillService;

/**
 * @Description: 车间任务/订单
 * @Author: jeecg-boot
 * @Date:   2020-09-02
 * @Version: V1.0
 */
@Service
public class ZzShoporderServiceImpl extends ServiceImpl<ZzShoporderMapper, ZzShoporder> implements IZzShoporderService {

	@Autowired
	private ZzShoporderMapper zzShoporderMapper;
	@Autowired
	private ZrkOrderProcessMapper zrkOrderProcessMapper;
	@Autowired
	private IZrkShoporderService zrkShoporderService;
	@Autowired
	private IBasCustomerService customerService;
	@Autowired
	private IZrkQzOrderService qzOrderService;
	@Autowired
	private IZrkProductCustomerService zrkProductCustomerService;
	@Autowired
	private IZrkMesFqParamService fqParamService;
	@Autowired
	private IStkPickUpBillService stkPickUpBillService;
	@Autowired
	private IStkPickUpEntryService pickUpEntryService;
	@Autowired
	private IStkIoBillService stkIoBillService;
	@Autowired
	private IStkIoBillEntryService stkIoBillEntryService;
	@Autowired
	private IStkInventoryService inventoryService;
	@Autowired
	private IBasMaterialCategoryService categoryService;
	@Autowired
	private IBasMaterialService materialService;
	@Autowired
	private IScan2ndService scan2ndService;
	@Autowired
	private IBasMeasureUnitService unitService;
	@Autowired
	private IBasMaterialTempService materialTempService;
	@Autowired
	private IStkIoMaterialLogService logService;
	@Autowired
	private ISysBaseAPI sysBaseAPI;

	
	@Override
	@Transactional
	public void delMain(String id) {
		zrkOrderProcessMapper.deleteByMainId(id);
		zzShoporderMapper.deleteById(id);
	}

	@Override
	@Transactional
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			zrkOrderProcessMapper.deleteByMainId(id.toString());
			zzShoporderMapper.deleteById(id);
		}
	}
	
	@Override
	public Result<?> getCustomer(String orderId) {
		// TODO Auto-generated method stub
		if(StringUtils.isBlank(orderId)) {
			return Result.error("请填写订单信息");
		}
		String[] ids = StringUtils.split(orderId, ",");
		List<String> idList = Arrays.asList(ids);
		LambdaQueryWrapper<ZzShoporder> query = new LambdaQueryWrapper<>();
		query.in(ZzShoporder::getId, idList);
		List<ZzShoporder> list = this.list(query);
		if(null == list || list.size() == 0) {
			return Result.ok(new ArrayList<BasCustomer>());
		}
		List<String> noList = Lists.newArrayList();
		for (ZzShoporder order : list) {
			String orderNo = order.getOrderNo();
			noList.add(orderNo);
		}
		LambdaQueryWrapper<ZrkShoporder> zrkQuery = new LambdaQueryWrapper<>();
		zrkQuery.in(ZrkShoporder::getOrderNo, noList);
		List<ZrkShoporder> zrkList = zrkShoporderService.list(zrkQuery);
		if(null == zrkList || zrkList.size() == 0) {
			return Result.ok(new ArrayList<BasCustomer>());
		}
		List<String> customerIds = Lists.newArrayList();
		for (ZrkShoporder zrkShoporder : zrkList) {
			customerIds.add(zrkShoporder.getCustomerId());
		}
		LambdaQueryWrapper<BasCustomer> cusQuery = new LambdaQueryWrapper<>();
		cusQuery.in(BasCustomer::getId, customerIds);
		List<BasCustomer> cusList = this.customerService.list(cusQuery);
		return Result.ok(cusList);
	}

	@Override
	@Transactional
	public Result<?> createPart(CreatePartVO createPart) {
		// TODO Auto-generated method stub
		String qzId = createPart.getQzId();
		if(createPart.getTaskFQList()==null || createPart.getTaskFQList().size()<1){
			return Result.error("参数不完整");
		}
		ZzShoporder shoporder = getById(qzId);
		if(null == shoporder) {
			return Result.error("未查询到切张单信息");
		}
		int num=0;
		for (CreatePartFQVO createPartFQVO : createPart.getTaskFQList()) {

			BigDecimal number = createPartFQVO.getNumber();
			Date endTime = createPartFQVO.getEndTime();
			String model = createPartFQVO.getModel();
			if (null == number || null == endTime || StringUtils.isBlank(model) || StringUtils.isBlank(qzId)) {
				return Result.error("参数不完整");
			}
			String remark = createPartFQVO.getRemark();
			String qzWoCode = shoporder.getWoCode();
//		List<ZzShoporder> qzscOrder = this.getQZSCOrder(qzWoCode);
			String newWoCode = "QZSC-" + qzWoCode + "-" + ++num;
//		if(qzscOrder != null) {
//			this.removeById(qzscOrder.getId());
//		}
			shoporder.getWoCustomerfile();
			ZzShoporder partOrder = new ZzShoporder();
			partOrder.setWoCode(newWoCode);
			partOrder.setCategoryId(shoporder.getCategoryId());
			partOrder.setCustomerName(shoporder.getCustomerName());
			partOrder.setWoPartname(shoporder.getWoPartname());
			partOrder.setOrderName(shoporder.getOrderNo());
			partOrder.setWoPartcode(this.sysBaseAPI.getNoByCode("productNO"));
			partOrder.setIsPush(0);
			partOrder.setProcessId(MaterialConstant.PROCESS_PART);
			partOrder.setSpecs(model);
			partOrder.setRemark(remark);
			partOrder.setWoQuantity(number.intValue());
			partOrder.setWoPlanstarttime(DateUtil.date());
			partOrder.setWoPlanendtime(endTime);
			partOrder.setWoDeliverytime(endTime);
			partOrder.setWoType("1");
			partOrder.setWoPriority(2);
			partOrder.setWoStatus(1);
			partOrder.setOrderName("切张工序派发工单");
			partOrder.setFormulaId(shoporder.getFormulaId());
			partOrder.setOrderNo(shoporder.getOrderNo());

			boolean saveFlag = this.save(partOrder);
			if (!saveFlag) {
				return Result.error("保存失败");
			}
		}
		return Result.ok("操作成功");
	}
	
	private ZzShoporder getQZSCOrder(String newWoCode) {
		LambdaQueryWrapper<ZzShoporder> query = new LambdaQueryWrapper<>();
		query.eq(ZzShoporder::getWoCode, newWoCode);
		List<ZzShoporder> list = list(query);
		if(null != list && 0 < list.size()) {
			return list.get(0);
		}
		
		return null;
	}

	private List<ZzShoporder> getQZSCOrders(String newWoCode) {
		LambdaQueryWrapper<ZzShoporder> query = new LambdaQueryWrapper<>();
		query.like(ZzShoporder::getWoCode, newWoCode);
		List<ZzShoporder> list = list(query);
		if(null != list && 0 < list.size()) {
			return list;
		}

		return null;
	}

	@Override
	@Transactional
	public Result<?> splitPartMes(SplitMesVO splitMes) {
		String parentMesId = splitMes.getParentMesId();
		System.out.println(JSON.toJSONString(splitMes));
		List<CreateMesVO> mesList = splitMes.getMesList();
		if(StringUtils.isBlank(parentMesId) || (null == mesList || 0 == mesList.size())) {
			return Result.error("参数不完整");
		}
		ZrkQzOrder parentOrder = this.qzOrderService.getById(parentMesId);
		if(null == parentOrder) {
			return Result.error("参数不完整");
		}
		String status = parentOrder.getMesOrderStatus();
		if(null != status && status.equals("4")) {
			return Result.error("MES单已生产完成，不能拆单");
		}
		if(null != status && status.equals("5")) {
			return Result.error("MES单已中止，不能拆单");
		}
		if(null != status && status.equals("6")) {
			return Result.error("MES单已拆单，不能继续拆单");
		}
		int num=00;
		for (CreateMesVO mes : mesList) {
			String userIds = mes.getUserId();
			String deviceId = mes.getDeviceId();
			List<ProductCustomVO> customerList = mes.getCustomerList();
			List<SplitParamVO> splitList = mes.getSplitList();
			String cate = parentOrder.getMaterialId();
			ZrkQzOrder qzOrder = new ZrkQzOrder();
//			String mesCode = FillRuleUtil.executeRule("mes_code", null).toString();
			String code=parentOrder.getCode();
//			code = code.substring(code.lastIndexOf('-')+1);
			StringBuffer mesCode=new StringBuffer();
			mesCode.append(code);
			mesCode.append("-");
			mesCode.append(++num);
			qzOrder.setParentId(parentMesId);
			qzOrder.setIsFinish(0);
			qzOrder.setIsSalary("1");
			qzOrder.setOperatorUsers(userIds);
			qzOrder.setMachineId(deviceId);
			qzOrder.setCode(mesCode.toString());
			qzOrder.setMaterialId(cate);
			qzOrder.setIsPush(1);
			qzOrder.setWoDeliverytime(parentOrder.getWoDeliverytime());
			qzOrder.setCustomerName(parentOrder.getCustomerName());
			qzOrder.setProcessId(parentOrder.getProcessId());
			qzOrder.setOrderProcessId(parentOrder.getOrderProcessId());
			qzOrder.setMesOrderStatus("1");
			qzOrder.setRemark(mes.getRemark());
			if(oConvertUtils.isNotEmpty(parentOrder.getFormulaId())) {
				qzOrder.setFormulaId(parentOrder.getFormulaId());
			}
			this.qzOrderService.save(qzOrder);
			
			for (SplitParamVO vo : splitList) {
				String parId = vo.getPartParamId();
				ZrkMesFqParam fqParam = this.fqParamService.getById(parId);
				if(null == fqParam) {
					return Result.error("参数错误");
				}
				BigDecimal count = vo.getSplitCount();
				
				ZrkMesFqParam param = new ZrkMesFqParam();
				param.setMesId(qzOrder.getId());
				param.setCategoryId(fqParam.getCategoryId());
				param.setWidth(fqParam.getWidth());
				param.setHeight(fqParam.getHeight());
				param.setModel(fqParam.getModel());
				param.setQuantity(count);
				param.setUnitId(fqParam.getUnitId());
				param.setPartParam(fqParam.getPartParam());
				param.setRemark(fqParam.getRemark());
				this.fqParamService.save(param);
			}
			
			List<ZrkProductCustomer> customers = Lists.newLinkedList();
			for (ProductCustomVO vo : customerList) {
				String partProjectId = vo.getPartProjectId();
				if(StringUtils.isBlank(partProjectId)) {
					return Result.error("参数错误");
				}
				ZrkProductCustomer oldCustomer = zrkProductCustomerService.getById(partProjectId);
				String remark = vo.getRemark();
				ZrkProductCustomer zrkproductCustomer = new ZrkProductCustomer();
				zrkproductCustomer.setMesId(qzOrder.getId());
				zrkproductCustomer.setWidth(oldCustomer.getWidth());
				zrkproductCustomer.setLength(oldCustomer.getLength());
				zrkproductCustomer.setCustomId(oldCustomer.getCustomId());
				zrkproductCustomer.setProductNumber(vo.getProductNumber());
				if(StringUtils.isBlank(remark)) {
					zrkproductCustomer.setRemark(oldCustomer.getRemark());
				} else {
					zrkproductCustomer.setRemark(remark);
				}
				String categoryId = oldCustomer.getCategoryId();
				if(StringUtils.isBlank(categoryId)) {
					zrkproductCustomer.setCategoryId(cate);
				}else {
					zrkproductCustomer.setCategoryId(categoryId);
				}
				zrkproductCustomer.setModel(vo.getModel());
				customers.add(zrkproductCustomer);
			}
			zrkProductCustomerService.saveBatch(customers);
		}
		//修改MES单状态为已拆单
		parentOrder.setMesOrderStatus("6");
		this.qzOrderService.updateById(parentOrder);
		return Result.ok("拆单成功");
	}


	@Override
	@Transactional
	public Result<?> splitPartMesQz(SplitMesVO splitMes) {
		String parentMesId = splitMes.getParentMesId();
		List<CreateMesVO> mesList = splitMes.getMesList();
		if(StringUtils.isBlank(parentMesId) || (null == mesList || 0 == mesList.size())) {
			return Result.error("参数不完整");
		}
		ZrkQzOrder parentOrder = this.qzOrderService.getById(parentMesId);
		if(null == parentOrder) {
			return Result.error("参数不完整");
		}
		String status = parentOrder.getMesOrderStatus();
		if(null != status && status.equals("4")) {
			return Result.error("MES单已生产完成，不能拆单");
		}
		if(null != status && status.equals("5")) {
			return Result.error("MES单已中止，不能拆单");
		}
		if(null != status && status.equals("6")) {
			return Result.error("MES单已拆单，不能继续拆单");
		}
		int num=00;
		for (CreateMesVO mes : mesList) {
			//保存子单mes单信息
			String userIds = mes.getUserId();
			String deviceId = mes.getDeviceId();
			String cate = parentOrder.getMaterialId();
			ZrkQzOrder qzOrder = new ZrkQzOrder();
//			String code = FillRuleUtil.executeRule("mes_code", null).toString();
			String code=parentOrder.getCode();
//			code = code.substring(code.lastIndexOf('-')+1);
			StringBuffer mesCode=new StringBuffer();
			mesCode.append(code);
			mesCode.append("-");
			mesCode.append(++num);
			qzOrder.setParentId(parentMesId);//原单id
			qzOrder.setIsFinish(0);//是否完成
			qzOrder.setIsSalary("1");//结算工资
			qzOrder.setOperatorUsers(userIds);//操作员（多个的时候,分割）
			qzOrder.setMachineId(deviceId);//机器
			qzOrder.setCode(mesCode.toString());//code
			qzOrder.setMaterialId(cate);//物料
			qzOrder.setIsPush(1);//是否推送
			qzOrder.setWoDeliverytime(parentOrder.getWoDeliverytime());//交货时间
			qzOrder.setCustomerName(parentOrder.getCustomerName());//客户
			qzOrder.setProcessId(parentOrder.getProcessId());//工序id
			qzOrder.setOrderProcessId(parentOrder.getOrderProcessId());//任务单id
			qzOrder.setMesOrderStatus("1");//生产状态
			qzOrder.setFormulaId(parentOrder.getFormulaId());//配方
			qzOrder.setProductNum(mes.getProductNum());//数量
			qzOrder.setSpecs(parentOrder.getSpecs());
			qzOrder.setRemark(mes.getRemark());
			this.qzOrderService.save(qzOrder);
		}
		//修改MES单状态为已拆单
		parentOrder.setMesOrderStatus("6");
		this.qzOrderService.updateById(parentOrder);
		return Result.ok("拆单成功");
	}

	@Override
	@Transactional
	public Result<?> splitPartMesFH(SplitMesVO splitMes) {
		String parentMesId = splitMes.getParentMesId();
		List<CreateMesVO> mesList = splitMes.getMesList();
		if(StringUtils.isBlank(parentMesId) || (null == mesList || 0 == mesList.size())) {
			return Result.error("参数不完整");
		}
		ZrkQzOrder parentOrder = this.qzOrderService.getById(parentMesId);
		if(null == parentOrder) {
			return Result.error("参数不完整");
		}
		String status = parentOrder.getMesOrderStatus();
		if(null != status && status.equals("4")) {
			return Result.error("MES单已生产完成，不能拆单");
		}
		if(null != status && status.equals("5")) {
			return Result.error("MES单已中止，不能拆单");
		}
		if(null != status && status.equals("6")) {
			return Result.error("MES单已拆单，不能继续拆单");
		}
		int num=00;
		for (CreateMesVO mes : mesList) {
			//保存子单mes单信息
			String userIds = mes.getUserId();
			String deviceId = mes.getDeviceId();
			String cate = parentOrder.getMaterialId();
			ZrkQzOrder fhOrder = new ZrkQzOrder();
//			String code = FillRuleUtil.executeRule("mes_code", null).toString();
			String code=parentOrder.getCode();
//			code = code.substring(code.lastIndexOf('-')+1);
			StringBuffer mesCode=new StringBuffer();
			mesCode.append(code);
			mesCode.append("-");
			mesCode.append(++num);
			fhOrder.setParentId(parentMesId);//原单id
			fhOrder.setIsFinish(0);//是否完成
			fhOrder.setIsSalary("1");//结算工资
			fhOrder.setOperatorUsers(userIds);//操作员（多个的时候,分割）
			fhOrder.setMachineId(deviceId);//机器
			fhOrder.setCode(mesCode.toString());//code
			fhOrder.setMaterialId(cate);//物料
			fhOrder.setIsPush(1);//是否推送
			fhOrder.setWoDeliverytime(parentOrder.getWoDeliverytime());//交货时间
			fhOrder.setCustomerName(parentOrder.getCustomerName());//客户
			fhOrder.setProcessId(parentOrder.getProcessId());//工序id
			fhOrder.setOrderProcessId(parentOrder.getOrderProcessId());//任务单id
			fhOrder.setMesOrderStatus("1");//生产状态
			fhOrder.setFormulaId(parentOrder.getFormulaId());//配方
			fhOrder.setProductNum(parentOrder.getProductNum());//数量
			fhOrder.setSpecs(mes.getSpecs());
			fhOrder.setRemark(mes.getRemark());
			this.qzOrderService.save(fhOrder);
		}
		//修改MES单状态为已拆单
		parentOrder.setMesOrderStatus("6");
		//修改父单排序状态为99
		parentOrder.setSort("99");
		this.qzOrderService.updateById(parentOrder);
		return Result.ok("拆单成功");
	}
	@Override
	@Transactional
	public Result<?> splitTask(SplitTaskVO splitTask) {
		String parentTaskId = splitTask.getParentTaskId();
		List<CreateTaskVo> taskList = splitTask.getTaskList();
		if(StringUtils.isBlank(parentTaskId) || (null == taskList || 0 == taskList.size())) {
			return Result.error("参数不完整");
		}
		ZzShoporder parentOrder = this.zzShoporderMapper.selectById(parentTaskId);
		if(null == parentOrder) {
			return Result.error("参数不完整");
		}
		Integer status = parentOrder.getWoStatus();
		if(null != status && status.equals("3")) {
			return Result.error("任务单已开始生产，不能拆单");
		}
		if(null != status && status.equals("4")) {
			return Result.error("任务单已生产完成，不能拆单");
		}
		if(null != status && status.equals("5")) {
			return Result.error("任务单已撤单，不能拆单");
		}
		if(null != status && status.equals("6")) {
			return Result.error("任务单已拆单，不能继续拆单");
		}
		for (CreateTaskVo task : taskList) {
			//保存子单任务单信息

			ZzShoporder zsd = new ZzShoporder();
			zsd.setIsPush(0);
			zsd.setProcessId(parentOrder.getProcessId());
			zsd.setOrderName("系统分派任务工单");
			zsd.setOrderNo(parentOrder.getOrderNo());
			zsd.setSpecs(parentOrder.getSpecs());//规格
			zsd.setWoCode(this.sysBaseAPI.getNoByCode("work_no"));
			zsd.setWoPlanstarttime(parentOrder.getWoPlanstarttime());
			zsd.setWoPlanendtime(parentOrder.getWoPlanendtime());
			zsd.setCategoryId(parentOrder.getCategoryId());
			zsd.setWoDeliverytime(parentOrder.getWoDeliverytime());
			zsd.setWoPartcode(this.sysBaseAPI.getNoByCode("productNO"));
			zsd.setWoPartname(parentOrder.getWoPartname());
			zsd.setWoQuantity(task.getProductNum());
			zsd.setWoType("1");
			zsd.setWoPriority(2);
			zsd.setWoStatus(1);
			zsd.setFacialSupplier(parentOrder.getFacialSupplier());
			zsd.setGlueSupplier(parentOrder.getGlueSupplier());
			zsd.setPaperSupplier(parentOrder.getPaperSupplier());
			zsd.setCustomerName(parentOrder.getCustomerName());
//			String formulaId = parentOrder.getFormulaId();
//			String sdf = null;
//			if(StringUtils.isNotBlank(formulaId)) {
//				zsd.setFormulaId(parentOrder.getFormulaId());
//				LambdaQueryWrapper<BasPfMaterial> query = new LambdaQueryWrapper<>();
//				query.eq(BasPfMaterial::getPfid, formulaId);
//				List<BasPfMaterial> list = pfMaterialService.list(query);
//				sdf = "原料名称：";
//				for (BasPfMaterial pf : list) {
//					String categoryId = pf.getPfName();
//					BasMaterialCategory category = this.basMaterialCategoryService.getById(categoryId);
//					sdf += category.getName() + " " + category.getCode() + ",";
//				}
//				sdf = sdf.substring(0, sdf.length()-1);
//			}
//			String remark = parentOrder.getRemark();//获取总订单的
//			if(null == remark) {
//				zsd.setRemark(sdf);
//			}
//			else {
//				if(sdf != null) {
//					zsd.setRemark(remark + "," + sdf);
//				} else {
//					zsd.setRemark(remark);
//				}
//			}
			zsd.setRemark(task.getRemark());
			this.zzShoporderMapper.insert(zsd);
		}
		//修改MES单状态为已拆单
		parentOrder.setWoStatus(6);
		this.zzShoporderMapper.updateById(parentOrder);
		return Result.ok("拆单成功");
	}

	@Override
	@Transactional
	public Result<?> recallQzOrFq(String id) {
		ZzShoporder zz = this.getById(id);
		String qzWoCode = zz.getWoCode();
		String newWoCode = "QZSC-" + qzWoCode;
		List<ZzShoporder> qzShopOrders =getQZSCOrders(newWoCode);
		List<String> ids=Lists.newArrayList();
		if(qzShopOrders != null &&qzShopOrders.size()>0) {
			for (ZzShoporder qzShopOrder : qzShopOrders) {
				if(!qzShopOrder.getWoStatus().equals(1)){
					return Result.error("撤回任务单失败！任务单已经生成MES单");
				}
				ids.add(qzShopOrder.getId());
			}
			this.removeByIds(ids);
		}
		return Result.ok("撤回成功");
	}


	@Override
	public Result<?> recallDelivery(String id) {
		// TODO Auto-generated method stub
		ZzShoporder zz = this.getById(id);
		if(zz==null) {
			return Result.error("未找到工单");
		}
		List<StkPickUpBill> billList = stkPickUpBillService.getByMesId(zz.getOrderNo());
		//根据销售订单号查提货单，若能查到，则是直接出库
		if(billList!=null && billList.size()>0) {
			Result<?> result = sysBaseAPI.sendRecallDeliveryMessage(id);
			if(result.isSuccess()) {
				zz.setWoStatus(1);
				this.baseMapper.updateById(zz);
			}
			
			return Result.ok("撤回成功");
		}
		
		return Result.error("撤单失败");
	}

	@Override
	@Transactional
	public Result<?> recall(String id) {
		ZzShoporder zz = this.getById(id);
		//通过id查询MES单的生产状态
		List<ZrkQzOrder> zrkQzOrders = qzOrderService.getQzOrderByOrderProcessId(zz.getId());
		if (zrkQzOrders == null || zrkQzOrders.size() == 0) {
			zz.setWoStatus(1);
			this.updateById(zz);
			return Result.ok("无需撤单，该任务单尚未生成MES单");
		}
		for (ZrkQzOrder zrkQzOrder : zrkQzOrders) {
			//撤回合并单时将非撤回id的任务单状态调整为1
			String[] orderId = zrkQzOrder.getOrderProcessId().split(",");
			//首先踢出生产完成的
			if (zrkQzOrder.getMesOrderStatus().equals("4")) {
				return Result.error("MES单无法撤回。生产已完成");
			}
			if (zrkQzOrder.getMesOrderStatus().equals("3")) {
				return Result.error("MES单无法撤回。生产已开始生产");
			}
			if(StringUtils.equals("1", zrkQzOrder.getMesOrderStatus())
					|| StringUtils.equals("2", zrkQzOrder.getMesOrderStatus())) {
				recallMaterial(zrkQzOrder);
			}
			sysBaseAPI.sendCheDanMessage(zrkQzOrder.getId());
			//判断工序
			//复合工序。直接修改状态
			if(zrkQzOrder.getProcessId().equals(MaterialConstant.PROCESS_ZJ)){
				//如果不是生产中--生产状态为未出货或者出货完成
				ZzShoporder zzShoporder = new ZzShoporder();
				zzShoporder.setWoStatus(1);
				zzShoporder.setId(id);
				this.updateById(zzShoporder);
				//MES单逻辑删除。取消列表页面显示
				updatePickAndOrder(zrkQzOrder);
			}
			if (zrkQzOrder.getProcessId().equals(MaterialConstant.PROCESS_COMPOUND)) {
				ischaidan(zrkQzOrder);
				//如果不是生产中--生产状态为未出货或者出货完成
				ZzShoporder zzShoporder = new ZzShoporder();
				zzShoporder.setWoStatus(1);
				zzShoporder.setId(id);
				this.updateById(zzShoporder);
				//MES单逻辑删除。取消列表页面显示
				updatePickAndOrder(zrkQzOrder);
			} else if (zrkQzOrder.getProcessId().equals(MaterialConstant.PROCESS_CUTTING_NORMAL)
					|| zrkQzOrder.getProcessId().equals(MaterialConstant.PROCESS_CUTTING_BIG)) {
				String qzWoCode = zz.getWoCode();
				String newWoCode = "QZSC-" + qzWoCode;
				List<ZzShoporder> qzShopOrders = getQZSCOrders(newWoCode);
				if (qzShopOrders != null && qzShopOrders.size() > 0) {
					for (ZzShoporder qzShopOrder : qzShopOrders) {
//							//修改分切单的状态
						qzOrFqStatusUpdate(qzShopOrder, zrkQzOrder);
						ischaidan(zrkQzOrder);
						ZzShoporder zzShoporder = new ZzShoporder();
						zzShoporder.setWoStatus(1);
						zzShoporder.setId(id);
						this.updateById(zzShoporder);
						//MES单逻辑删除。取消列表页面显示
						updatePickAndOrder(zrkQzOrder);
					}
				} else {
					//修改分切单的状态
					qzOrFqStatusUpdate(zz, zrkQzOrder);
					//修改切张单的状态
					ZzShoporder zzShoporder = new ZzShoporder();
					zzShoporder.setId(zz.getId());
					zzShoporder.setWoStatus(1);
					this.updateById(zzShoporder);
					//MES单逻辑删除。取消列表页面显示
					updatePickAndOrder(zrkQzOrder);
				}
			} else if (zrkQzOrder.getProcessId().equals(MaterialConstant.PROCESS_PART)) {
				ischaidan(zrkQzOrder);
				if (orderId.length > 0) {
					for (String s : orderId) {
						if (!s.equals(id)) {
							ZzShoporder zzShoporder = new ZzShoporder();
							zzShoporder.setWoStatus(1);
							zzShoporder.setId(s);
							this.updateById(zzShoporder);
						}
					}
				}

				ZzShoporder zzShoporder = new ZzShoporder();
				zzShoporder.setWoStatus(1);
				zzShoporder.setId(id);
				this.updateById(zzShoporder);
				//MES单逻辑删除。取消列表页面显示
				updatePickAndOrder(zrkQzOrder);
			}
		}
		return Result.ok("撤回成功");
	}

	/**
	 * 如果生产状态为1/2则直接修改状态为中止撤回
	 * @param zzShoporder
	 * @param zrkQzOrder
	 * @return
	 */
	public boolean updateStatus(ZzShoporder zzShoporder, ZrkQzOrder zrkQzOrder) {
		boolean f = false;
		if (zrkQzOrder.getMesOrderStatus().equals("1") || zrkQzOrder.getMesOrderStatus().equals("2")) {
			zzShoporder.setWoStatus(1);
			this.updateById(zzShoporder);
			//mes单/提货单状态修改为中止
			f= updatePickAndOrder(zrkQzOrder);
		}
		return f;
	}

	/**
	 * 修改MES单状态还有提货单状态
	 * @param zrkQzOrder
	 * @return
	 */
	public boolean updatePickAndOrder(ZrkQzOrder zrkQzOrder){
		boolean flag=false;
		//MES单逻辑删除。取消列表页面显示
		zrkQzOrder.setIsFinish(0);
		zrkQzOrder.setIsChedan("1");
		zrkQzOrder.setDelFlag("1");
		zrkQzOrder.setMesOrderStatus("2");
		qzOrderService.updateById(zrkQzOrder);
		qzOrderService.removeById(zrkQzOrder);
		//根据mes单id查询提货单信息。进行逻辑删除
		List<StkPickUpBill> stkPickUpBill= stkPickUpBillService.getByMesId(zrkQzOrder.getId());
		for (StkPickUpBill pickUpBill : stkPickUpBill) {
			pickUpBill.setDelFlag("1");
			stkPickUpBillService.removeById(pickUpBill);
			flag=true;
		}
		return flag;
	}

	@Transactional
	private Result<?> recallMaterial(ZrkQzOrder zrkQzOrder){
		//根据源单（mes单）查询出入库信息
		LambdaQueryWrapper<StkIoBill> query = new LambdaQueryWrapper<>();
		query.eq(StkIoBill::getSourceId, zrkQzOrder.getId());
		query.orderByDesc(StkIoBill::getCreateTime);
		List<StkIoBill> stkIoBillList = stkIoBillService.list(query);
		Iterator<StkIoBill> it = stkIoBillList.iterator();
		StkIoBill outBill = null;
		//记录生产出库的四种类型
		List<String> productOutTypes = CollUtil.newArrayList("2991", "2992", "2993", "2997");
		while(it.hasNext()) {
			StkIoBill bill = it.next();
			if(productOutTypes.contains(bill.getStockIoType())) {
				//判断出库类型，找到物料的出库记录
				outBill = bill;
				break;
			}
		}
		List<StkIoBillEntry> ioBillEntryList = null;
		if(null != outBill&&!StringUtils.equals(outBill.getStockIoType(), "1994")) {
			ioBillEntryList = stkIoBillEntryService.selectByMainId(outBill.getId());
		}
		if(ioBillEntryList!=null&&ioBillEntryList.size()>0) {
			Date date = DateUtils.gettimestamp();
			String billNo = this.sysBaseAPI.getNoByCode("stock_io_bill_no");
			LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
			String userName = sysUser.getUsername();
			//封装复合半成品入库单信息
			StkIoBill bill = new StkIoBill();
			bill.setBillNo(billNo);
			bill.setStockIoType("1994");
			bill.setBillDate(date);
			bill.setIsAuto(1);
			bill.setClerkId(userName);
			bill.setHandlerId(userName);
			bill.setIsApproved(1);
			bill.setCreateBy(userName);
			bill.setCreateTime(date);
			bill.setIsRubric(0);
			bill.setSourceType(ScanServiceImpl.PRODUCTION_SOURCE_TYPE);
			bill.setSourceId(zrkQzOrder.getId());
			bill.setSourceNo(zrkQzOrder.getCode());
			bill.setBillProcStatus(ScanServiceImpl.BILL_STATUS_APPROVAL);
			bill.setSysOrgCode(sysUser.getOrgCode());
			bill.setSupplierId(CommonConstant.QY_SUPPLIER_ID);
			bill.setRemark("生产退库");
			List<StkIoBillEntry> entryList = new LinkedList<>();
			int i = 1;
			for(StkIoBillEntry entry:ioBillEntryList) {
				String warehouseId = entry.getWarehouseId();
				//封装出入库记录
				StkIoMaterialLog log = StkIoMaterialLog.builder()
						.materialId(entry.getMaterialId())
						.ioType("1994")
						.procedureId(zrkQzOrder.getId())
						.amount(entry.getQty()).build();
				BigDecimal cost = scan2ndService.getMaterialCost(log);
				if(cost == null) {
					cost = BigDecimal.ZERO;
				}
				//计算物料平方数
				BasMeasureUnit unit = this.unitService.getById(entry.getUnitId());
				if(null == unit) {
					return Result.error("未找到物料单位");
				}
				BasMaterial material = this.materialService.getById(entry.getMaterialId());
				//取出长宽
				BigDecimal length = entry.getLength();
				BigDecimal width = entry.getWidth();
				BigDecimal number = entry.getQty();
				BigDecimal square = null;
				if ("吨".equals(unit.getName())) {
					BigDecimal outQty = entry.getQty();
					BigDecimal preSquare = material.getSquare();
					if(null != preSquare && null != outQty) {
						square = number.divide(outQty, 10, BigDecimal.ROUND_DOWN).multiply(preSquare);
						square = square.setScale(4, BigDecimal.ROUND_DOWN);
					} else {
						if(null != width && null != length) {
							square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
							square.setScale(2, BigDecimal.ROUND_DOWN);
							String model = width.toString() + "*" + length.toString();
							material.setModel(model);
						}
					}
				} else if ("平方".equals(unit.getName())) {
					square = number;
				} else {
					if(null != width && null != length) {
						square = width.divide(new BigDecimal(100), 4, BigDecimal.ROUND_DOWN).multiply(length);
						square.setScale(2, BigDecimal.ROUND_DOWN);
						String model = width.toString() + "*" + length.toString();
						material.setModel(model);
					}
				}
				//物料信息维护
				material.setLength(length);
				material.setWidth(width);
				material.setUnitId(unit.getId());
				material.setSquare(square);
				this.materialService.updateById(material);
				BasMaterialTemp materialTemp = this.materialTempService.getByCode(material.getCode());
				//维护物料数量
				materialTemp.setAmount(number);
				this.materialTempService.updateById(materialTemp);
				
				StkIoBillEntry billEntry = new StkIoBillEntry();
				billEntry.setMaterialId(material.getId());
				billEntry.setBillNo(billNo);
				billEntry.setMid(bill.getId());
				billEntry.setBatchNo(billNo + "-10");
				billEntry.setQty(number);
				billEntry.setCost(cost);
				if(width != null) {
					billEntry.setWidth(width);
				}
				if(length != null) {
					billEntry.setLength(length);
				}
				billEntry.setUnitId(material.getUnitId());
				billEntry.setWarehouseId(warehouseId);
				billEntry.setSettleQty(number);
				billEntry.setEntryNo(i);
				entryList.add(billEntry);
				logService.insertLog(bill.getId(), date, billEntry.getId(), bill.getStockIoType(), 0, material, unit.getId(), zrkQzOrder.getId(), 1, cost, billEntry.getQty(), zrkQzOrder.getProcessId());
				i++;
			}
			this.stkIoBillService.saveMain(bill, entryList);
			this.stkIoBillService.updateInventory(bill, entryList);
		}
		return Result.ok();
	}

	private Result<?> ischaidan(ZrkQzOrder zrkQzOrder) {
		if (zrkQzOrder.getMesOrderStatus().equals("6")) {
			List<ZrkQzOrder> qzOrders = qzOrderService.getQzOrderByParentId(zrkQzOrder.getId());
			if (qzOrders.size() > 0 && qzOrders != null) {
				for (ZrkQzOrder order : qzOrders) {
					if (order.getMesOrderStatus().equals("3")) {
						return Result.ok("无法撤回" + order.getCode() + "单未中止");
					}
				}
			}
			for (ZrkQzOrder qzOrder : qzOrders) {
				qzOrder.setIsFinish(0);
				qzOrder.setIsChedan("1");
				qzOrderService.removeById(qzOrder);
			}
		}
		return null;
	}

	/**
	 * 切张单生成的分切单的撤回状态修改
	 * @param zzShoporder
	 * @param zrkQzOrder
	 * @return
	 */
	public Result<?> qzOrFqStatusUpdate(ZzShoporder zzShoporder, ZrkQzOrder zrkQzOrder) {

		String qzOrFqId = zzShoporder.getId();//需要修改的切张单所生成的分切单的id
		List<String> ids = Lists.newArrayList();
		ids.add(qzOrFqId);
		String[] qfIds = zrkQzOrder.getOrderProcessId().split(",");
		for (String qfId : qfIds) {
			ids.add(qfId);//切张单的id
		}
		boolean f = true;
		List<ZrkQzOrder> qzOrders = qzOrderService.getQzOrderByParentId(zrkQzOrder.getId());
		if (qzOrders.size() > 0 && qzOrders != null) {
			for (ZrkQzOrder order : qzOrders) {
				if (order.getMesOrderStatus().equals("3")) {
					return Result.error("无法撤销，未中止MES单Code：" + order.getCode());
				}
			}
		}
		for (String id : ids) {
			ZzShoporder zz = new ZzShoporder();
			if (qzOrFqId.equals(id)) {
				//如果是
				zz.setWoStatus(1);
				zz.setDelFlag("1");
			} else {
				zz.setWoStatus(1);
			}
			zz.setId(id);
			this.updateById(zz);
		}
		return Result.ok("撤回成功");

	}

	/**
	 * 根据销售订单编号查询任务单信息
	 * @param orderNo
	 * @return
	 */
	public List<ZzShoporder> selectOrderByOrderNo(String orderNo){
		return zzShoporderMapper.getShopOrderByOrderNo(orderNo);
	}

	@Override
	public Result<?> directShip(CreatePickVO createPickVO){
		List<PickUpVo> pickUps = createPickVO.getList();
		ZzShoporder zzShoporder=zzShoporderMapper.selectById(createPickVO.getOrderId());
//		zrkShoporder=new ZrkShoporder();
		if(zzShoporder!=null){
			zzShoporder.setWoStatus(6);
			zzShoporderMapper.updateById(zzShoporder);
		}else{
			return Result.error("操作失败。未找到任务单");
		}
		ZrkShoporder zrkShoporder=zrkShoporderService.selectByOrderCode(zzShoporder.getOrderNo());
		if(zrkShoporder!=null){
			zrkShoporder.setOrderStatus("9");
			zrkShoporderService.updateById(zrkShoporder);
		}else{
			return Result.error("操作失败。未找到销售订单");
		}
		//新增提货单
		StkPickUpBill pickUpBill = new StkPickUpBill();
		pickUpBill.setProcessId(zzShoporder.getProcessId());
		pickUpBill.setOrderId(zzShoporder.getId());
		pickUpBill.setBillStatus("0");
		String billNo = this.sysBaseAPI.getNoByCode("pick_up_bill_no");
		pickUpBill.setBillNo(billNo);
//		pickUpBill.setDeviceId(zzShoporder.getCategoryId());//设备
		pickUpBill.setIsEnabled(1);
		pickUpBill.setMesId(zrkShoporder.getOrderNo());
		pickUpBill.setType("1");
		this.stkPickUpBillService.save(pickUpBill);
		List<StkPickUpEntry> entryList = Lists.newArrayList();
		for (PickUpVo pickUpVo : pickUps) {
			String materialCodes = pickUpVo.getMaterialCode();
			if(StringUtils.isBlank(materialCodes) && (null == pickUpVo.getNumber() || BigDecimal.ZERO.compareTo(pickUpVo.getNumber()) >= 0)) {
				continue;
			}
			if(StringUtils.isBlank(materialCodes)) {
				String categoryId = pickUpVo.getCategoryId();
				BasMaterialCategory category = this.categoryService.getById(categoryId);
				StkPickUpEntry entry = new StkPickUpEntry();
				entry.setBillId(pickUpBill.getId());
				entry.setIsOut("0");
				entry.setNumber(pickUpVo.getNumber());
				entry.setUnitId(category.getUnitId());
				entry.setCategoryId(pickUpVo.getCategoryId());
				entry.setModel(pickUpVo.getModel());
				entry.setRemark(pickUpVo.getRemark());
				entryList.add(entry);
			} else {
				String[] materialCodeArray = StringUtils.split(materialCodes, ",");
				for (int i = 0; i < materialCodeArray.length; i++) {
					String code = materialCodeArray[i];
					BasMaterial material = materialService.getMaterialByCode(code);
					String materialId = material.getId();
					StkInventory inventory = inventoryService.selectLatestByMaterial(materialId);
					StkPickUpEntry entry = new StkPickUpEntry();
					entry.setBillId(pickUpBill.getId());
					entry.setIsOut("0");
					entry.setUnitId(material.getUnitId());
					entry.setMaterialCode(code);
					entry.setMaterialId(materialId);
					entry.setWarehouseId(inventory.getWarehouseId());
					entry.setModel(material.getModel());
					entry.setRemark(pickUpVo.getRemark());
					entryList.add(entry);
				}
			}
		}
		this.pickUpEntryService.saveBatch(entryList);
		sysBaseAPI.sendDdMessage(pickUpBill.getId(),zzShoporder.getId());
		return Result.ok("生成成功");
	}




}
